home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / idlelib / run.py < prev    next >
Text File  |  2005-10-18  |  11KB  |  323 lines

  1. import sys
  2. import os
  3. import linecache
  4. import time
  5. import socket
  6. import traceback
  7. import thread
  8. import threading
  9. import Queue
  10.  
  11. import CallTips
  12. import RemoteDebugger
  13. import RemoteObjectBrowser
  14. import StackViewer
  15. import rpc
  16.  
  17. import __main__
  18.  
  19. LOCALHOST = '127.0.0.1'
  20.  
  21. try:
  22.     import warnings
  23. except ImportError:
  24.     pass
  25. else:
  26.     def idle_formatwarning_subproc(message, category, filename, lineno):
  27.         """Format warnings the IDLE way"""
  28.         s = "\nWarning (from warnings module):\n"
  29.         s += '  File \"%s\", line %s\n' % (filename, lineno)
  30.         line = linecache.getline(filename, lineno).strip()
  31.         if line:
  32.             s += "    %s\n" % line
  33.         s += "%s: %s\n" % (category.__name__, message)
  34.         return s
  35.     warnings.formatwarning = idle_formatwarning_subproc
  36.  
  37. # Thread shared globals: Establish a queue between a subthread (which handles
  38. # the socket) and the main thread (which runs user code), plus global
  39. # completion and exit flags:
  40.  
  41. exit_now = False
  42. quitting = False
  43.  
  44. def main(del_exitfunc=False):
  45.     """Start the Python execution server in a subprocess
  46.  
  47.     In the Python subprocess, RPCServer is instantiated with handlerclass
  48.     MyHandler, which inherits register/unregister methods from RPCHandler via
  49.     the mix-in class SocketIO.
  50.  
  51.     When the RPCServer 'server' is instantiated, the TCPServer initialization
  52.     creates an instance of run.MyHandler and calls its handle() method.
  53.     handle() instantiates a run.Executive object, passing it a reference to the
  54.     MyHandler object.  That reference is saved as attribute rpchandler of the
  55.     Executive instance.  The Executive methods have access to the reference and
  56.     can pass it on to entities that they command
  57.     (e.g. RemoteDebugger.Debugger.start_debugger()).  The latter, in turn, can
  58.     call MyHandler(SocketIO) register/unregister methods via the reference to
  59.     register and unregister themselves.
  60.  
  61.     """
  62.     global exit_now
  63.     global quitting
  64.     global no_exitfunc
  65.     no_exitfunc = del_exitfunc
  66.     port = 8833
  67.     #time.sleep(15) # test subprocess not responding
  68.     if sys.argv[1:]:
  69.         port = int(sys.argv[1])
  70.     sys.argv[:] = [""]
  71.     sockthread = threading.Thread(target=manage_socket,
  72.                                   name='SockThread',
  73.                                   args=((LOCALHOST, port),))
  74.     sockthread.setDaemon(True)
  75.     sockthread.start()
  76.     while 1:
  77.         try:
  78.             if exit_now:
  79.                 try:
  80.                     exit()
  81.                 except KeyboardInterrupt:
  82.                     # exiting but got an extra KBI? Try again!
  83.                     continue
  84.             try:
  85.                 seq, request = rpc.request_queue.get(0)
  86.             except Queue.Empty:
  87.                 time.sleep(0.05)
  88.                 continue
  89.             method, args, kwargs = request
  90.             ret = method(*args, **kwargs)
  91.             rpc.response_queue.put((seq, ret))
  92.         except KeyboardInterrupt:
  93.             if quitting:
  94.                 exit_now = True
  95.             continue
  96.         except SystemExit:
  97.             raise
  98.         except:
  99.             type, value, tb = sys.exc_info()
  100.             try:
  101.                 print_exception()
  102.                 rpc.response_queue.put((seq, None))
  103.             except:
  104.                 # Link didn't work, print same exception to __stderr__
  105.                 traceback.print_exception(type, value, tb, file=sys.__stderr__)
  106.                 exit()
  107.             else:
  108.                 continue
  109.  
  110. def manage_socket(address):
  111.     for i in range(3):
  112.         time.sleep(i)
  113.         try:
  114.             server = MyRPCServer(address, MyHandler)
  115.             break
  116.         except socket.error, err:
  117.             print>>sys.__stderr__,"IDLE Subprocess: socket error: "\
  118.                                         + err[1] + ", retrying...."
  119.     else:
  120.         print>>sys.__stderr__, "IDLE Subprocess: Connection to "\
  121.                                "IDLE GUI failed, exiting."
  122.         show_socket_error(err, address)
  123.         global exit_now
  124.         exit_now = True
  125.         return
  126.     server.handle_request() # A single request only
  127.  
  128. def show_socket_error(err, address):
  129.     import Tkinter
  130.     import tkMessageBox
  131.     root = Tkinter.Tk()
  132.     root.withdraw()
  133.     if err[0] == 61: # connection refused
  134.         msg = "IDLE's subprocess can't connect to %s:%d.  This may be due "\
  135.               "to your personal firewall configuration.  It is safe to "\
  136.               "allow this internal connection because no data is visible on "\
  137.               "external ports." % address
  138.         tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root)
  139.     else:
  140.         tkMessageBox.showerror("IDLE Subprocess Error", "Socket Error: %s" % err[1])
  141.     root.destroy()
  142.  
  143. def print_exception():
  144.     import linecache
  145.     linecache.checkcache()
  146.     flush_stdout()
  147.     efile = sys.stderr
  148.     typ, val, tb = excinfo = sys.exc_info()
  149.     sys.last_type, sys.last_value, sys.last_traceback = excinfo
  150.     tbe = traceback.extract_tb(tb)
  151.     print>>efile, '\nTraceback (most recent call last):'
  152.     exclude = ("run.py", "rpc.py", "threading.py", "Queue.py",
  153.                "RemoteDebugger.py", "bdb.py")
  154.     cleanup_traceback(tbe, exclude)
  155.     traceback.print_list(tbe, file=efile)
  156.     lines = traceback.format_exception_only(typ, val)
  157.     for line in lines:
  158.         print>>efile, line,
  159.  
  160. def cleanup_traceback(tb, exclude):
  161.     "Remove excluded traces from beginning/end of tb; get cached lines"
  162.     orig_tb = tb[:]
  163.     while tb:
  164.         for rpcfile in exclude:
  165.             if tb[0][0].count(rpcfile):
  166.                 break    # found an exclude, break for: and delete tb[0]
  167.         else:
  168.             break        # no excludes, have left RPC code, break while:
  169.         del tb[0]
  170.     while tb:
  171.         for rpcfile in exclude:
  172.             if tb[-1][0].count(rpcfile):
  173.                 break
  174.         else:
  175.             break
  176.         del tb[-1]
  177.     if len(tb) == 0:
  178.         # exception was in IDLE internals, don't prune!
  179.         tb[:] = orig_tb[:]
  180.         print>>sys.stderr, "** IDLE Internal Exception: "
  181.     rpchandler = rpc.objecttable['exec'].rpchandler
  182.     for i in range(len(tb)):
  183.         fn, ln, nm, line = tb[i]
  184.         if nm == '?':
  185.             nm = "-toplevel-"
  186.         if not line and fn.startswith("<pyshell#"):
  187.             line = rpchandler.remotecall('linecache', 'getline',
  188.                                               (fn, ln), {})
  189.         tb[i] = fn, ln, nm, line
  190.  
  191. def flush_stdout():
  192.     try:
  193.         if sys.stdout.softspace:
  194.             sys.stdout.softspace = 0
  195.             sys.stdout.write("\n")
  196.     except (AttributeError, EOFError):
  197.         pass
  198.  
  199. def exit():
  200.     """Exit subprocess, possibly after first deleting sys.exitfunc
  201.  
  202.     If config-main.cfg/.def 'General' 'delete-exitfunc' is True, then any
  203.     sys.exitfunc will be removed before exiting.  (VPython support)
  204.  
  205.     """
  206.     if no_exitfunc:
  207.         del sys.exitfunc
  208.     sys.exit(0)
  209.  
  210. class MyRPCServer(rpc.RPCServer):
  211.  
  212.     def handle_error(self, request, client_address):
  213.         """Override RPCServer method for IDLE
  214.  
  215.         Interrupt the MainThread and exit server if link is dropped.
  216.  
  217.         """
  218.         global quitting
  219.         try:
  220.             raise
  221.         except SystemExit:
  222.             raise
  223.         except EOFError:
  224.             global exit_now
  225.             exit_now = True
  226.             thread.interrupt_main()
  227.         except:
  228.             erf = sys.__stderr__
  229.             print>>erf, '\n' + '-'*40
  230.             print>>erf, 'Unhandled server exception!'
  231.             print>>erf, 'Thread: %s' % threading.currentThread().getName()
  232.             print>>erf, 'Client Address: ', client_address
  233.             print>>erf, 'Request: ', repr(request)
  234.             traceback.print_exc(file=erf)
  235.             print>>erf, '\n*** Unrecoverable, server exiting!'
  236.             print>>erf, '-'*40
  237.             quitting = True
  238.             thread.interrupt_main()
  239.  
  240.  
  241. class MyHandler(rpc.RPCHandler):
  242.  
  243.     def handle(self):
  244.         """Override base method"""
  245.         executive = Executive(self)
  246.         self.register("exec", executive)
  247.         sys.stdin = self.console = self.get_remote_proxy("stdin")
  248.         sys.stdout = self.get_remote_proxy("stdout")
  249.         sys.stderr = self.get_remote_proxy("stderr")
  250.         import IOBinding
  251.         sys.stdin.encoding = sys.stdout.encoding = \
  252.                              sys.stderr.encoding = IOBinding.encoding
  253.         self.interp = self.get_remote_proxy("interp")
  254.         rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05)
  255.  
  256.     def exithook(self):
  257.         "override SocketIO method - wait for MainThread to shut us down"
  258.         time.sleep(10)
  259.  
  260.     def EOFhook(self):
  261.         "Override SocketIO method - terminate wait on callback and exit thread"
  262.         global quitting
  263.         quitting = True
  264.         thread.interrupt_main()
  265.  
  266.     def decode_interrupthook(self):
  267.         "interrupt awakened thread"
  268.         global quitting
  269.         quitting = True
  270.         thread.interrupt_main()
  271.  
  272.  
  273. class Executive:
  274.  
  275.     def __init__(self, rpchandler):
  276.         self.rpchandler = rpchandler
  277.         self.locals = __main__.__dict__
  278.         self.calltip = CallTips.CallTips()
  279.  
  280.     def runcode(self, code):
  281.         try:
  282.             self.usr_exc_info = None
  283.             exec code in self.locals
  284.         except:
  285.             self.usr_exc_info = sys.exc_info()
  286.             if quitting:
  287.                 exit()
  288.             # even print a user code SystemExit exception, continue
  289.             print_exception()
  290.             jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>")
  291.             if jit:
  292.                 self.rpchandler.interp.open_remote_stack_viewer()
  293.         else:
  294.             flush_stdout()
  295.  
  296.     def interrupt_the_server(self):
  297.         thread.interrupt_main()
  298.  
  299.     def start_the_debugger(self, gui_adap_oid):
  300.         return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid)
  301.  
  302.     def stop_the_debugger(self, idb_adap_oid):
  303.         "Unregister the Idb Adapter.  Link objects and Idb then subject to GC"
  304.         self.rpchandler.unregister(idb_adap_oid)
  305.  
  306.     def get_the_calltip(self, name):
  307.         return self.calltip.fetch_tip(name)
  308.  
  309.     def stackviewer(self, flist_oid=None):
  310.         if self.usr_exc_info:
  311.             typ, val, tb = self.usr_exc_info
  312.         else:
  313.             return None
  314.         flist = None
  315.         if flist_oid is not None:
  316.             flist = self.rpchandler.get_remote_proxy(flist_oid)
  317.         while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]:
  318.             tb = tb.tb_next
  319.         sys.last_type = typ
  320.         sys.last_value = val
  321.         item = StackViewer.StackTreeItem(flist, tb)
  322.         return RemoteObjectBrowser.remote_object_tree_item(item)
  323.